use std::str::FromStr;

use crate::{DomNode, NodeType};

/// 选择器类型枚举
#[derive(Debug, Clone, PartialEq)]
pub enum Selector {
    // 基本选择器
    Tag(String),   // 标签选择器: div
    Id(String),    // ID选择器: #id
    Class(String), // 类选择器: .class

    // 属性选择器
    Attribute {
        name: String,
        operator: AttributeOperator,
        value: Option<String>,
    }, // 属性选择器: [attr], [attr=value]

    // 伪类选择器
    PseudoClass(String, Option<Box<Selector>>), // 伪类选择器: :first-child, :nth-child(n)

    // 组合选择器
    Descendant(Box<Selector>, Box<Selector>), // 后代选择器: div p
    Child(Box<Selector>, Box<Selector>),      // 子元素选择器: div > p
    Adjacent(Box<Selector>, Box<Selector>),   // 相邻兄弟选择器: div + p
    Sibling(Box<Selector>, Box<Selector>),    // 通用兄弟选择器: div ~ p

    // 组合
    And(Vec<Selector>), // 组合选择器: div.class#id
    Or(Vec<Selector>),  // 多选择器: div, span
}

/// 属性选择器操作符
#[derive(Debug, Clone, PartialEq)]
pub enum AttributeOperator {
    Exists,         // [attr]
    Equals,         // [attr=value]
    Contains,       // [attr*=value]
    StartsWith,     // [attr^=value]
    EndsWith,       // [attr$=value]
    WordContains,   // [attr~=value]
    HyphenContains, // [attr|=value]
}

// 确保SelectorParseError是公开的
#[derive(Debug)]
pub struct SelectorParseError(pub String);

impl FromStr for Selector {
    type Err = SelectorParseError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let s = s.trim();

        // 解析组合选择器
        if s.contains(',') {
            let selectors = s
                .split(',')
                .map(|part| part.trim().parse())
                .collect::<Result<Vec<_>, _>>()?;
            return Ok(Selector::Or(selectors));
        }

        // 解析后代选择器
        if s.contains(' ') && !s.contains('>') {
            let parts: Vec<&str> = s.split_whitespace().collect();
            if parts.len() == 2 {
                return Ok(Selector::Descendant(
                    Box::new(parts[0].parse()?),
                    Box::new(parts[1].parse()?),
                ));
            }
        }

        // 解析子元素选择器
        if s.contains('>') {
            let parts: Vec<&str> = s
                .split('>')
                .map(|s| s.trim())
                .filter(|s| !s.is_empty())
                .collect();
            if parts.len() == 2 {
                return Ok(Selector::Child(
                    Box::new(parts[0].parse()?),
                    Box::new(parts[1].parse()?),
                ));
            }
        }

        // 解析相邻兄弟选择器
        if s.contains('+') {
            let parts: Vec<&str> = s
                .split('+')
                .map(|s| s.trim())
                .filter(|s| !s.is_empty())
                .collect();
            if parts.len() == 2 {
                return Ok(Selector::Adjacent(
                    Box::new(parts[0].parse()?),
                    Box::new(parts[1].parse()?),
                ));
            }
        }

        // 解析通用兄弟选择器
        if s.contains('~') {
            let parts: Vec<&str> = s
                .split('~')
                .map(|s| s.trim())
                .filter(|s| !s.is_empty())
                .collect();
            if parts.len() == 2 {
                return Ok(Selector::Sibling(
                    Box::new(parts[0].parse()?),
                    Box::new(parts[1].parse()?),
                ));
            }
        }

        // 解析伪类选择器
        if s.contains(':') {
            let parts: Vec<&str> = s.split(':').collect();
            if parts.len() == 2 {
                let base = if !parts[0].is_empty() {
                    Some(Box::new(parts[0].parse()?))
                } else {
                    None
                };

                let pseudo = parts[1];
                // 处理带参数的伪类
                if pseudo.contains('(') && pseudo.ends_with(')') {
                    let param_start = pseudo.find('(').unwrap();
                    let name = &pseudo[..param_start];
                    let param = &pseudo[param_start + 1..pseudo.len() - 1];

                    return match base {
                        Some(base_selector) => Ok(Selector::And(vec![
                            *base_selector,
                            Selector::PseudoClass(name.to_string(), Some(Box::new(param.parse()?))),
                        ])),
                        None => Ok(Selector::PseudoClass(
                            name.to_string(),
                            Some(Box::new(param.parse()?)),
                        )),
                    };
                } else {
                    return match base {
                        Some(base_selector) => Ok(Selector::And(vec![
                            *base_selector,
                            Selector::PseudoClass(pseudo.to_string(), None),
                        ])),
                        None => Ok(Selector::PseudoClass(pseudo.to_string(), None)),
                    };
                }
            }
        }

        // 解析属性选择器
        if s.starts_with('[') && s.ends_with(']') {
            let attr_content = &s[1..s.len() - 1];

            // 检查各种属性操作符
            if let Some(pos) = attr_content.find("*=") {
                let (name, value) = attr_content.split_at(pos);
                let value = &value[2..];
                return Ok(Selector::Attribute {
                    name: name.to_string(),
                    operator: AttributeOperator::Contains,
                    value: Some(value.trim_matches('"').trim_matches('\'').to_string()),
                });
            } else if let Some(pos) = attr_content.find("^=") {
                let (name, value) = attr_content.split_at(pos);
                let value = &value[2..];
                return Ok(Selector::Attribute {
                    name: name.to_string(),
                    operator: AttributeOperator::StartsWith,
                    value: Some(value.trim_matches('"').trim_matches('\'').to_string()),
                });
            } else if let Some(pos) = attr_content.find("$=") {
                let (name, value) = attr_content.split_at(pos);
                let value = &value[2..];
                return Ok(Selector::Attribute {
                    name: name.to_string(),
                    operator: AttributeOperator::EndsWith,
                    value: Some(value.trim_matches('"').trim_matches('\'').to_string()),
                });
            } else if let Some(pos) = attr_content.find("~=") {
                let (name, value) = attr_content.split_at(pos);
                let value = &value[2..];
                return Ok(Selector::Attribute {
                    name: name.to_string(),
                    operator: AttributeOperator::WordContains,
                    value: Some(value.trim_matches('"').trim_matches('\'').to_string()),
                });
            } else if let Some(pos) = attr_content.find("|=") {
                let (name, value) = attr_content.split_at(pos);
                let value = &value[2..];
                return Ok(Selector::Attribute {
                    name: name.to_string(),
                    operator: AttributeOperator::HyphenContains,
                    value: Some(value.trim_matches('"').trim_matches('\'').to_string()),
                });
            } else if let Some(pos) = attr_content.find('=') {
                let (name, value) = attr_content.split_at(pos);
                let value = &value[1..];
                return Ok(Selector::Attribute {
                    name: name.to_string(),
                    operator: AttributeOperator::Equals,
                    value: Some(value.trim_matches('"').trim_matches('\'').to_string()),
                });
            } else {
                return Ok(Selector::Attribute {
                    name: attr_content.to_string(),
                    operator: AttributeOperator::Exists,
                    value: None,
                });
            }
        }

        // 解析简单选择器组合 (如 div.class#id)
        let mut selectors = Vec::new();

        // 尝试解析ID
        if let Some(id_pos) = s.find('#') {
            let (before, after) = s.split_at(id_pos);

            // 处理前面的部分 (可能包含标签和类)
            if !before.is_empty() {
                if let Ok(selector) = before.parse() {
                    selectors.push(selector);
                }
            }

            // 提取ID (直到下一个特殊字符)
            let mut id_end = after.len();
            for (i, c) in after.chars().enumerate().skip(1) {
                if c == '.' || c == '#' || c == '[' || c == ':' {
                    id_end = i;
                    break;
                }
            }

            selectors.push(Selector::Id(after[1..id_end].to_string()));

            // 如果ID后面还有内容，递归处理
            if id_end < after.len() {
                if let Ok(remaining_selector) = after[id_end..].parse() {
                    if let Selector::And(mut nested_selectors) = remaining_selector {
                        selectors.append(&mut nested_selectors);
                    } else {
                        selectors.push(remaining_selector);
                    }
                }
            }

            if selectors.len() > 1 {
                return Ok(Selector::And(selectors));
            } else if selectors.len() == 1 {
                return Ok(selectors.pop().unwrap());
            }
        }

        // 尝试解析类
        if let Some(class_pos) = s.find('.') {
            let (before, after) = s.split_at(class_pos);

            // 处理前面的部分 (可能是标签)
            if !before.is_empty() {
                selectors.push(Selector::Tag(before.to_string()));
            }

            // 提取类名 (直到下一个特殊字符)
            let mut class_end = after.len();
            for (i, c) in after.chars().enumerate().skip(1) {
                if c == '.' || c == '#' || c == '[' || c == ':' {
                    class_end = i;
                    break;
                }
            }

            selectors.push(Selector::Class(after[1..class_end].to_string()));

            // 如果类后面还有内容，递归处理
            if class_end < after.len() {
                if let Ok(remaining_selector) = after[class_end..].parse() {
                    if let Selector::And(mut nested_selectors) = remaining_selector {
                        selectors.append(&mut nested_selectors);
                    } else {
                        selectors.push(remaining_selector);
                    }
                }
            }

            if selectors.len() > 1 {
                return Ok(Selector::And(selectors));
            } else if selectors.len() == 1 {
                return Ok(selectors.pop().unwrap());
            }
        }

        // 如果以上都不匹配，则视为标签选择器
        if s.starts_with('#') {
            Ok(Selector::Id(s[1..].to_string()))
        } else if s.starts_with('.') {
            Ok(Selector::Class(s[1..].to_string()))
        } else {
            Ok(Selector::Tag(s.to_string()))
        }
    }
}

impl Selector {
    /// 检查节点是否匹配选择器
    pub fn matches(&self, node: &DomNode) -> bool {
        match self {
            Selector::Tag(tag) => {
                if let NodeType::Element(node_tag) = &node.node_type {
                    node_tag.as_ref() == tag
                } else {
                    false
                }
            }

            Selector::Id(id) => {
                if let Some(node_id) = node.get_attribute("id") {
                    node_id == id
                } else {
                    false
                }
            }

            Selector::Class(class) => {
                if let Some(class_attr) = node.get_attribute("class") {
                    class_attr.split_whitespace().any(|c| c == class)
                } else {
                    false
                }
            }

            Selector::Attribute {
                name,
                operator,
                value,
            } => match value {
                None => node.get_attribute(name).is_some(),
                Some(val) => {
                    if let Some(attr_val) = node.get_attribute(name) {
                        match operator {
                            AttributeOperator::Exists => true,
                            AttributeOperator::Equals => attr_val == val,
                            AttributeOperator::Contains => attr_val.contains(val),
                            AttributeOperator::StartsWith => attr_val.starts_with(val),
                            AttributeOperator::EndsWith => attr_val.ends_with(val),
                            AttributeOperator::WordContains => {
                                attr_val.split_whitespace().any(|word| word == val)
                            }
                            AttributeOperator::HyphenContains => {
                                attr_val == val || attr_val.starts_with(&format!("{}-", val))
                            }
                        }
                    } else {
                        false
                    }
                }
            },

            Selector::PseudoClass(name, arg) => {
                match name.as_str() {
                    "first-child" => self.is_first_child(node),
                    "empty" => self.is_empty(node),
                    // 其他伪类可以在这里实现
                    _ => false,
                }
            }

            Selector::Descendant(parent, child) => {
                if child.matches(node) {
                    self.has_matching_ancestor(node, parent)
                } else {
                    false
                }
            }

            Selector::Child(parent, child) => {
                if child.matches(node) {
                    if let Some(parent_ref) = &node.parent {
                        let parent_node = parent_ref.borrow();
                        parent.matches(&parent_node)
                    } else {
                        false
                    }
                } else {
                    false
                }
            }

            Selector::Adjacent(prev, next) => {
                // 相邻兄弟选择器暂未实现
                false
            }

            Selector::Sibling(sibling, subject) => {
                // 通用兄弟选择器暂未实现
                false
            }

            Selector::And(selectors) => {
                // 所有选择器都必须匹配
                selectors.iter().all(|sel| sel.matches(node))
            }

            Selector::Or(selectors) => {
                // 任一选择器匹配即可
                selectors.iter().any(|sel| sel.matches(node))
            }
        }
    }

    // 辅助方法：检查节点是否有匹配指定选择器的祖先
    fn has_matching_ancestor(&self, node: &DomNode, selector: &Selector) -> bool {
        if let Some(parent_ref) = &node.parent {
            let parent = parent_ref.borrow();
            if selector.matches(&parent) {
                return true;
            }
            return self.has_matching_ancestor(&parent, selector);
        }
        false
    }

    // 判断节点是否是其父节点的第一个子元素
    fn is_first_child(&self, node: &DomNode) -> bool {
        if let Some(parent_ref) = &node.parent {
            let parent = parent_ref.borrow();
            if !parent.children.is_empty() {
                // 查找第一个元素类型的子节点
                for child in &parent.children {
                    if let NodeType::Element(_) = &child.node_type {
                        // 由于无法直接比较引用相等，比较节点类型和属性
                        if std::ptr::eq(child, node) {
                            return true;
                        }
                        return false; // 找到第一个元素，但不是当前节点
                    }
                }
            }
        }
        false
    }

    // 判断节点是否没有子元素
    fn is_empty(&self, node: &DomNode) -> bool {
        node.children.is_empty()
    }

    /// 检查节点是否匹配:first-child伪类
    fn matches_first_child(&self, node: &DomNode) -> bool {
        if let Some(parent_rc) = &node.parent {
            let parent = parent_rc.borrow();
            if !parent.children.is_empty() {
                // 检查节点是否为父节点的第一个子元素节点
                let first_element = parent.children.iter().find(|child| {
                    if let NodeType::Element(_) = &child.node_type {
                        true
                    } else {
                        false
                    }
                });

                if let Some(first) = first_element {
                    return std::ptr::eq(first, node);
                }
            }
        }
        false
    }

    /// 检查节点是否匹配:last-child伪类
    fn matches_last_child(&self, node: &DomNode) -> bool {
        if let Some(parent_rc) = &node.parent {
            let parent = parent_rc.borrow();

            // 从后向前查找第一个元素节点
            let last_element = parent.children.iter().rev().find(|child| {
                if let NodeType::Element(_) = &child.node_type {
                    true
                } else {
                    false
                }
            });

            if let Some(last) = last_element {
                return std::ptr::eq(last, node);
            }
        }
        false
    }

    /// 检查节点是否匹配:empty伪类
    fn matches_empty(&self, node: &DomNode) -> bool {
        // 空元素：没有子元素且没有文本内容
        for child in &node.children {
            match &child.node_type {
                NodeType::Element(_) => return false,
                NodeType::Text(text) if !text.trim().is_empty() => return false,
                _ => {}
            }
        }
        true
    }
}
